package com.lion.seaman.common.tools;


import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * json处理工具
 *
 * @author 李永曜
 * @time 2014-7-9下午11:39:13
 * <p>
 * jackson 的注解:
 * <p>
 * •@JsonIgnoreProperties 此注解是类注解，作用是json序列化时将java
 * bean中的一些属性忽略掉，序列化和反序列化都受影响。<br/>
 * •@JsonIgnore此注解用于属性或者方法上（最好是get方法上），作用和上面的@JsonIgnoreProperties一样。<br/>
 * •@JsonFormat此注解用于属性或者方法上（最好是get方法上），可以方便的把Date类型直接转化为我们想要的模式，比如@JsonFormat
 * (pattern = "yyyy-MM-dd HH-mm-ss")<br/>
 * •@JsonSerialize此注解用于属性或者getter方法上，用于在序列化时嵌入我们自定义的代码，
 * 比如序列化一个double时在其后面限制两位小数点。<br/>
 * </p>
 * @see <a href="http://blog.csdn.net/nomousewch/article/details/8955796">blog</a>
 */
@SuppressWarnings("deprecation")
public class JsonTools {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, false);
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    private static final JsonFactory JSONFACTORY = new JsonFactory();

    public static String beanToJson(Object o) {
        StringWriter sw = new StringWriter(300);
        JsonGenerator jsonGenerator = null;

        try {
            jsonGenerator = JSONFACTORY.createJsonGenerator(sw);
            MAPPER.writeValue(jsonGenerator, o);
            return sw.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (jsonGenerator != null) {
                try {
                    jsonGenerator.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T jsonToBean(String json, Class<?> clazz) {
        try {
            return (T) MAPPER.readValue(json, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> beanToMap(Object o) {
        try {
            return MAPPER.readValue(beanToJson(o), HashMap.class);
        } catch (Exception e) {
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> jsonToMap(String json,
                                                boolean collToString) {
        try {
            Map<String, Object> map = MAPPER.readValue(json, HashMap.class);
            if (collToString) {
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    if (entry.getValue() instanceof Collection
                            || entry.getValue() instanceof Map) {
                        entry.setValue(beanToJson(entry.getValue()));
                    }
                }
            }
            return map;
        } catch (Exception e) {
            return null;
        }
    }

    public static String listToJson(List<Map<String, String>> list) {
        JsonGenerator jsonGenerator = null;
        StringWriter sw = new StringWriter();
        try {
            jsonGenerator = JSONFACTORY.createJsonGenerator(sw);
            new ObjectMapper().writeValue(jsonGenerator, list);
            jsonGenerator.flush();
            return sw.toString();
        } catch (Exception e) {
            return null;
        } finally {
            if (jsonGenerator != null) {
                try {
                    jsonGenerator.flush();
                    jsonGenerator.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static List<Map<String, String>> jsonToMapList(String json) {
        try {
            if (json != null && !"".equals(json.trim())) {
                JsonParser jsonParse = JSONFACTORY
                        .createJsonParser(new StringReader(json));

                ArrayList<Map<String, String>> arrayList = (ArrayList<Map<String, String>>) new ObjectMapper()
                        .readValue(jsonParse, ArrayList.class);
                return arrayList;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取泛型的Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> jsonToList(String json, Class<T> clazz) throws Exception {
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> list = (List<T>) MAPPER.readValue(json, javaType);
        return list;
    }

}